#pragma once
//yes
#include"noncopyable.h"
#include"MutexLock.h"
#include"Condition.h"
#include<queue>

/*
线程安全、阻塞的队列。队列使用std::deque双端队列，可以在队列首、尾插入或删除元素。

BlockingQueue类使用Mutex在这里插入代码片保护成员变量；为提高效率（出队take()操作比入队put()操作要频繁），
使用Condition变量，当读出数据时，发现这个队列是空的，就把这个线程挂起到条件变量上，当写入数据的时候就唤起所有正在等待条件变量的线程

*/
template<class T>
class BlockingQuene:noncopyable{
public:
    BlockingQuene()
        :mutex_(),
         notEmpty_(mutex_),
         quene_()
    {    
    }
    void put(const T& x){
        MutexLockGuard lock(mutex_);
        quene_.push_back(x);
        notEmpty_.notify();
    }
    T take(){
        MutexLockGuard lock(mutex_);
        while (quene_.empty())
        {
            notEmpty_.wait();
        }
        assert(!quene_.empty());
        T front(quene_.front());
        quene_.pop_front();
        return front;
    }
    bool empty(){
        return quene_.empty();
    }

    size_t size() const{
        MutexLockGuard lock(mutex_);
        return quene_.size();
    }
private:
    mutable MutexLock mutex_;
    Condition notEmpty_;
    std::deque<T> quene_;
};